<template>
  <div>
    <div>{{ name }}</div>
    <canvas id="canvas" ref="canvasRef" width="375" height="300"></canvas>
    <audio id="audio" ref="audioRef" :src="musicConfig.src" autoplay controls loop></audio>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, onMounted } from 'vue'
  // eslint-disable-next-line no-undef
  defineOptions({
    name: 'MyLike'
  })
  // https://www.cnblogs.com/BlueCc/p/14285681.html
  const musicConfig = reactive({
    src: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-3deb6ee7-4896-4b24-b0f0-edf6668149a2/89a502d3-6573-4260-be17-0822ccf3ec79.mp3'
  })
  const isPlay = ref(true)
  const audioRef = ref(null)
  const canvasRef = ref(null)

  class Audio {
    audioCtx
    analyser
    audio
    audioSrc
    freqArr
    constructor(audio: any, fftSize: any) {
      this.audioCtx = new AudioContext()
      this.analyser = this.audioCtx.createAnalyser()
      this.audio = audio
      this.audio.crossOrigin = 'anonymous'
      this.audioSrc = this.audioCtx.createMediaElementSource(this.audio)
      this.analyser.fftSize = fftSize
      this.audioSrc.connect(this.analyser)
      this.analyser.connect(this.audioCtx.destination)
      this.freqArr = new Uint8Array(this.analyser.frequencyBinCount)
    }
  }

  class Canvas {
    canvas
    analyser
    freqArr
    ctx
    meterWidth
    gap
    minHeight
    cwidth
    cheight
    capHeight
    meterNum
    constructor(canvas: any, audio: any, options: any = {}) {
      this.canvas = canvas
      this.analyser = audio.analyser
      this.freqArr = audio.freqArr
      this.ctx = canvas.getContext('2d')
      // 方块的宽度
      this.meterWidth = options.meterWidth || 5
      // 方块的间距
      this.gap = options.gap || 2
      // 方块最小高度
      this.minHeight = options.minHeight || 2
      this.cwidth = this.canvas.width
      this.cheight = this.canvas.height - 2
      this.capHeight = 0
      // 根据宽度和间距计算出可以放多少个方块
      this.meterNum = this.cwidth / (this.meterWidth + this.gap)
    }

    draw() {
      const gradient = this.ctx.createLinearGradient(0, 0, 0, 300)
      gradient.addColorStop(1, '#0f00f0')
      gradient.addColorStop(0.5, '#ff0ff0')
      gradient.addColorStop(0, '#f00f00')
      this.ctx.fillStyle = gradient
    }

    render() {
      const freqArr = new Uint8Array(this.analyser.frequencyBinCount)
      this.analyser.getByteFrequencyData(freqArr)
      // 从频谱数据中每隔step均匀取出meterNum个数据.
      const step = Math.round(freqArr.length / this.meterNum)
      this.ctx.clearRect(0, 0, this.cwidth, this.cheight)
      for (let i = 0; i < this.meterNum; i++) {
        const value = freqArr[i * step]
        // 绘制
        this.ctx.fillRect(
          i * (this.meterWidth + this.gap),
          this.cheight - value + this.capHeight,
          this.meterWidth,
          this.cheight || this.minHeight
        )
      }
      requestAnimationFrame(() => {
        this.render()
      })
    }
  }
  onMounted(() => {
    const audio = audioRef.value
    const canvas = canvasRef.value
    // 音频获取频谱部分
    console.log(123)
    const audioExp = new Audio(audio, 512)
    const canvasExp = new Canvas(canvas, audioExp)
    canvasExp.draw()
    canvasExp.render()
  })

  const props = defineProps({
    name: String
  })

  console.log('进入myLike的创建时机')
</script>
